<template>
  <a-spin :spinning="confirmLoading">
    <j-form-container :disabled="formDisabled">
      <!-- 主表单区域 -->
      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
        <a-row>
          <a-col :span="8">
            <a-form-model-item label="出库记录单号" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="entryNumber">
              <a-input v-model="model.recordNumber" placeholder="保存自动生成" disabled></a-input>
            </a-form-model-item>
          </a-col>
          <!--
          <a-col :span="8">
            <a-form-model-item label="审批流程" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="approvalFlow">
              <j-dict-select-tag
                type="list"
                v-model="model.approvalFlow"
                dictCode="outbound_record_flow"
                placeholder="请选择审批流程" />
            </a-form-model-item>
          </a-col>
          -->
          <a-col :span="8">
            <a-form-model-item label="出库日期" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="outboundDate">
              <j-date placeholder="请选择出库日期" v-model="model.outboundDate" style="width: 100%" />
            </a-form-model-item>
          </a-col>
          <a-col :span="8">
            <a-form-model-item label="备注" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="remark">
              <a-input v-model="model.remark" rows="4" placeholder="请输入备注" />
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
    <!-- 子表单区域 -->
    <a-tabs v-model="activeKey" @change="handleChangeTabs">
      <a-tab-pane tab="出库信息" :key="refKeys[0]" :forceRender="true">
        <j-vxe-table
          keep-source
          :ref="refKeys[0]"
          :loading="outboundOrderItemTable.loading"
          :columns="outboundOrderItemTable.columns"
          :dataSource="outboundOrderItemTable.dataSource"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="false"
          :toolbar="false"
        />
      </a-tab-pane>
      <a-tab-pane tab="明细信息" :key="refKeys[1]" :forceRender="true">
        <j-vxe-table
          keep-source
          :ref="refKeys[0]"
          :loading="outboundOrderItemTable.loading"
          :columns="outboundOrderItemTable.columns"
          :dataSource="outboundOrderItemTable.dataSource"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="true"
          :toolbar="false"
          row-selection-type="radio"
          @selectRowChange="handleSelectRowChange"
        >
        </j-vxe-table>
        <div class="ant-alert ant-alert-info" style="margin: 16px 0;">
          <i class="anticon anticon-info-circle ant-alert-icon"></i> <a
          style="font-weight: 600">{{ selectedKeys }}</a>项
        </div>
        <j-vxe-table
          keep-source
          ref="outboundRecordItem"
          :loading="outboundRecordItemTable.loading"
          :columns="outboundRecordItemTable.columns"
          :dataSource="outboundRecordItemList"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="false"
          :toolbar="false"
        />
      </a-tab-pane>
      <a-tab-pane tab="业务员指定批次" :key="refKeys[2]" :forceRender="true">
        <j-vxe-table
          keep-source
          ref="outboundOrderBatchItem"
          :loading="outboundOrderBatchItemTable.loading"
          :columns="outboundOrderBatchItemTable.columns"
          :dataSource="outboundOrderBatchItemTable.dataSource"
          :maxHeight="300"
          :disabled="formDisabled"
          :rowNumber="true"
          :rowSelection="false"
          :toolbar="false"
        />
      </a-tab-pane>
    </a-tabs>
  </a-spin>
</template>

<script>

import { JVxeTableModelMixin } from '@/mixins/JVxeTableModelMixin.js'
import { JVXETypes } from '@/components/jeecg/JVxeTable'
import JFormContainer from '@/components/jeecg/JFormContainer'
import { getAction, postAction } from '@api/manage'
import { definitionStartByDataId, isFirstInitiator } from '@views/flowable/api/definition'
import dayjs from 'dayjs'
import utils from '@/utils/utils'

export default {
  name: 'OutboundRecordForm',
  mixins: [JVxeTableModelMixin],
  components: {
    JFormContainer
  },
  data() {
    return {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 7 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      },
      model: {
        warehouseCode: null
      },
      // 新增时子表默认添加几行空数据
      addDefaultRowNum: 1,
      validatorRules: {
        outboundType: [
          { required: true, message: '请输入出库类型!' }
        ],
        documentNumber: [
          { required: true, message: '请输入单据号!' }
        ],
        outboundNumber: [
          { required: true, message: '请输入出库单号!' }
        ],
        warehouseCode: [
          { required: true, message: '请输入领料仓库编码!' }
        ],
        outboundDate: [
          { required: true, message: '请输入出库日期!' }
        ]
      },
      refKeys: ['outboundOrderItem', 'outboundRecordItem', 'outboundOrderBatchItem'],
      tableKeys: ['outboundOrderItem', 'outboundOrderBatchItem'],
      activeKey: 'outboundOrderItem',
      // 出库信息
      outboundOrderItemTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            title: '客户物料编码',
            key: 'customerMaterialCode',
            type: JVXETypes.normal,
            minWidth: '110px'
          },
          {
            title: '物料编码',
            key: 'materialCode',
            type: JVXETypes.normal,
            minWidth: '110px'
          },
          {
            title: '物料名称',
            key: 'materialName',
            type: JVXETypes.normal,
            minWidth: '220px'
          },
          {
            title: '规格型号',
            key: 'specificationModel',
            type: JVXETypes.normal,
            width: '90px'
          },
          {
            title: '单位',
            key: 'unit_dictText',
            type: JVXETypes.normal,
            dictCode: 'ji_unit',
            width: '60px'
          },
          {
            title: '出库数量',
            key: 'quantity',
            type: JVXETypes.normal,
            width: '80px'
          },
          {
            title: '辅单位',
            key: 'secondaryUnit_dictText',
            type: JVXETypes.normal,
            dictCode: 'zl_unit',
            width: '70px'
          },
          {
            title: '辅数量',
            key: 'secondaryQuantity',
            type: JVXETypes.normal,
            width: '80px'
          },
          // {
          //   title: '库存可用数量',
          //   key: 'availableInventory',
          //   type: JVXETypes.normal,
          //   minWidth: '130px'
          // },
          {
            title: '制单人',
            key: 'createBy_dictText',
            type: JVXETypes.normal,
            minWidth: '100px'
          },
          {
            title: '制单部门',
            key: 'sysOrgCode_dictText',
            type: JVXETypes.normal,
            minWidth: '100px'
          },
          {
            title: '制单日期',
            key: 'createTime',
            type: JVXETypes.normal,
            minWidth: '150px'
          },
        ]
      },
      // 明细信息
      outboundRecordItemTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            title: '客户物料编码',
            key: 'customerMaterialCode',
            type: JVXETypes.normal,
            minWidth: '110px'
          },
          {
            title: '物料编码',
            key: 'materialCode',
            type: JVXETypes.normal,
            minWidth: '110px'
          },
          {
            title: '物料名称',
            key: 'materialName',
            type: JVXETypes.normal,
            minWidth: '220px'
          },
          {
            title: '规格型号',
            key: 'specificationModel',
            type: JVXETypes.normal,
            width: '90px'
          },
          {
            title: '单位',
            key: 'unit_dictText',
            type: JVXETypes.normal,
            dictCode: 'ji_unit',
            width: '60px'
          },
          {
            title: '库存数量',
            key: 'quantity',
            type: JVXETypes.normal,
            width: '80px'
          },
          {
            title: '辅单位',
            key: 'secondaryUnit_dictText',
            type: JVXETypes.normal,
            dictCode: 'zl_unit',
            width: '70px'
          },
          {
            title: '辅数量',
            key: 'secondaryQuantity',
            type: JVXETypes.normal,
            width: '80px'
          },
          {
            title: '生产日期',
            key: 'productionDate',
            type: JVXETypes.normal,
            width: '100px'
          },
          {
            title: '限用日期',
            key: 'expirationDate',
            type: JVXETypes.normal,
            width: '100px'
          },
          {
            title: '批次号',
            key: 'batchNumber',
            type: JVXETypes.normal,
            minWidth: '100px'
          },
          {
            title: '物料批号',
            key: 'materialBatchNumber',
            type: JVXETypes.normal,
            minWidth: '150px'
          },
          {
            title: '储位',
            key: 'storageLocation_dictText',
            type: JVXETypes.normal,
            minWidth: '150px'
          },
          {
            title: '入库日期',
            key: 'entryDate',
            type: JVXETypes.normal,
            width: '120px'
          },
          {
            title: '质检状态',
            key: 'qualityInspectionStatus_dictText',
            type: JVXETypes.normal,
            width: '80px'
          },
          {
            title: '通知出库数量',
            key: 'notifyOutboundQuantity',
            type: JVXETypes.inputNumber,
            width: '120px',
            placeholder: '请输入${title}',
            defaultValue: '',
            fixed: 'right',
            min: 0,
            validateRules: [
              { required: true, message: '${title}不能为空' },
              {
                handler({ cellValue, row, column }, callback, target) {
                  if (cellValue < 0) {
                    callback(false, '${title}不能小于0') 
                  } else {
                    callback(true)
                  }
                },
                message: '${title}不能为负数',
              }
            ]
          }
        ]
      },
      // 营销指定出库批次
      outboundOrderBatchItemTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            title: '客户物料编码',
            key: 'customerMaterialCode',
            type: JVXETypes.normal,
            minWidth: '110px'
          },
          {
            title: '物料编码',
            key: 'materialCode',
            type: JVXETypes.normal,
            minWidth: '110px'
          },
          {
            title: '物料名称',
            key: 'materialName',
            type: JVXETypes.normal,
            minWidth: '220px'
          },
          {
            title: '规格型号',
            key: 'specificationModel',
            type: JVXETypes.normal,
            width: '90px'
          },
          {
            title: '单位',
            key: 'unit_dictText',
            type: JVXETypes.normal,
            dictCode: 'ji_unit',
            width: '60px'
          },
          {
            title: '出库数量',
            key: 'quantity',
            type: JVXETypes.normal,
            width: '80px'
          },
          {
            title: '辅单位',
            key: 'secondaryUnit_dictText',
            type: JVXETypes.normal,
            dictCode: 'zl_unit',
            width: '70px'
          },
          {
            title: '辅数量',
            key: 'secondaryQuantity',
            type: JVXETypes.normal,
            width: '80px'
          },
          {
            title: '生产日期',
            key: 'productionDate',
            type: JVXETypes.normal,
            width: '100px'
          },
          {
            title: '限用日期',
            key: 'expirationDate',
            type: JVXETypes.normal,
            width: '100px'
          },
          {
            title: '批次号',
            key: 'batchNumber',
            type: JVXETypes.normal,
            minWidth: '100px'
          },
          {
            title: '物料批号',
            key: 'materialBatchNumber',
            type: JVXETypes.normal,
            minWidth: '150px'
          },
          {
            title: '储位',
            key: 'storageLocation_dictText',
            type: JVXETypes.normal,
            minWidth: '150px'
          },
          {
            title: '质检状态',
            key: 'qualityInspectionStatus_dictText',
            type: JVXETypes.normal,
            width: '80px'
          },
          {
            title: '通知出库数量',
            key: 'notifyOutboundQuantity',
            type: JVXETypes.input,
            width: '120px',
            fixed: 'right',
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{ required: true, message: '${title}不能为空' }]
          }
        ]
      },
      url: {
        add: '/wms/outbound/outbound-record/add',
        edit: '/wms/outbound/outbound-record/edit',
        outboundOrderItem: {
          list: '/wms/outbound/outbound-order/queryOutboundOrderItemByMainId'
        },
        outboundOrderBatchItem: {
          list: '/wms/outbound/outbound-order/queryOutboundOrderBatchItemByMainId'
        },
        inventory: {
          list: '/wms/inventory/list'
        }
      },
      currentMaterialCode: null
    }
  },
  props: {
    //表单禁用
    disabled: {
      type: Boolean,
      default: false,
      required: false
    }
  },
  computed: {
    formDisabled() {
      return this.disabled
    },
    selectedKeys() {
      return this.outboundRecordItemList.length
    },
    outboundRecordItemList() {
      if (!this.currentMaterialCode) {
        return []
      }
      return this.outboundRecordItemTable.dataSource.filter(item => {
        return item.materialCode === this.currentMaterialCode
      })
    }
  },
  created() {
  },
  methods: {
    insert(record) {
      if (!record) {
        return
      }
      this.insertBefore()
      this.model = Object.assign({}, record[0])
      this.model.outboundDate = dayjs().format('YYYY-MM-DD')
      this.insertAfter()
    },
    insertBefore() {
      this.outboundOrderItemTable.dataSource = []
      this.outboundRecordItemTable.dataSource = []
    },
    insertAfter() {
      this.$nextTick(() => {
      })
      // 加载子表数据
      if (this.model.id) {
        let params = { id: this.model.id }
        this.requestSubTableData(this.url.outboundOrderItem.list, params, this.outboundOrderItemTable, (res) => {
          if (this.outboundOrderItemTable.dataSource && this.outboundOrderItemTable.dataSource.length > 0) {
            const materialCodeList = this.outboundOrderItemTable.dataSource.map(item => item.materialCode)
            this.outboundOrderItemTable.dataSource.forEach((item) => {
              item.quantity = utils.sub(item.quantity, item.outboundQuantity)
            })
            this.fetchRecordItemData(this.model.warehouseCode, materialCodeList)
          }
        })
        this.requestSubTableData(this.url.outboundOrderBatchItem.list, params, this.outboundOrderBatchItemTable, (res) => {
          const { code, message } = res
          if (code !== 200) {
            this.$message.error(message)
            return
          }
          if (this.outboundOrderBatchItemTable.dataSource && this.outboundOrderBatchItemTable.dataSource.length > 0) {
            this.outboundOrderBatchItemTable.dataSource.forEach(item => {
              item.orderBatchItemId = item.id
              item.id = null
            })
          }
        })
      }
    },
    fetchRecordItemData(warehouseCode, materialCodeList) {
      getAction('/wms/inventory/listAll', { warehouseCode, materialCodeList, qualityInspectionStatus: '1' })
        .then((res) => {
          const { result } = res
          if (!result) {
            return
          }
          this.assignNotifyOutboundQuantities(result)
        })
    },
    assignNotifyOutboundQuantities(records) {
      const orderItems = [...this.outboundOrderItemTable.dataSource]
      const materialQuantityMap = Object.fromEntries(
        orderItems.map(item => [item.materialCode, item.quantity])
      )
      const result = []
      const groupedByMaterial = this.groupBy(records, 'materialCode')
      for (const materialCode in groupedByMaterial) {
        let remaining = materialQuantityMap[materialCode] || 0
        const groupRecords = groupedByMaterial[materialCode]
        for (const record of groupRecords) {
          if (remaining <= 0) {
            record.notifyOutboundQuantity = 0
          } else if (record.quantity <= remaining) {
            record.notifyOutboundQuantity = record.quantity
            remaining -= record.quantity
          } else {
            record.notifyOutboundQuantity = remaining
            remaining = 0
          }
          result.push(record)
        }
      }
      this.outboundRecordItemTable.dataSource = result
    },
    groupBy(array, key) {
      return array.reduce((acc, item) => {
        (acc[item[key]] = acc[item[key]] || []).push(item)
        return acc
      }, {})
    },
    handleSelectRowChange({ selectedRows, selectedRowIds }) {
      this.currentMaterialCode = selectedRows[0]?.materialCode
    },
    /** 整理成formData */
    classifyIntoFormData(allValues) {
      let main = Object.assign(this.model, allValues.formValue)
      return {
        ...main, // 展开
        outboundOrderItemList: allValues.tablesValue[0].tableData
      }
    },
    validateError(msg) {
      this.$message.error(msg)
    },
    async handleSubmit() {
      const validate = await this.$refs.form.validate()
      if (!validate) {
        return
      }
      const outboundRecordItem = this.outboundRecordItemTable.dataSource.filter(item => item.notifyOutboundQuantity)
      let count = 0;
      let notifyOutboundQuantity = 0;
      outboundRecordItem.forEach((item) =>{
        notifyOutboundQuantity = notifyOutboundQuantity + item.notifyOutboundQuantity;
        if(utils.sub(item.quantity, item.notifyOutboundQuantity) < 0){
          count = count + 1;
          this.validateError(item.materialName + ': 通知出库数量大于库存数量')
        }
      })
      if(count > 0){
        return
      }
      if(notifyOutboundQuantity == 0){
        this.validateError('通知出库数量为0')
        return
      }
      this.outboundOrderItemTable.dataSource.forEach((orderItem) =>{
        this.$set(orderItem, 'countOutQuantity', 0);
        outboundRecordItem.forEach((item) =>{
          if(item.materialCode == orderItem.materialCode){
            orderItem.countOutQuantity = orderItem.countOutQuantity + item.notifyOutboundQuantity
            // 保存orderitemId，用于更新已出库数量
            this.$set(item, 'orderItemId', orderItem.id);
          }
        })
      })
      const overOutQuantityItems = this.outboundOrderItemTable.dataSource.filter(item => utils.sub(item.countOutQuantity, item.quantity) > 0)
      if (overOutQuantityItems.length > 0) {
        this.validateError('通知出库数量大于未出库数量')
        return
      }
      if (!outboundRecordItem.length) {
        this.validateError('库存没有可用物料')
        this.activeKey = 'outboundRecordItem'
        return
      }
      const errMap = await this.$refs.outboundRecordItem.validateTable()
      if (errMap) {
        this.activeKey = 'outboundRecordItem'
        return
      }
      const errMap1 = await this.$refs.outboundOrderBatchItem.validateTable()
      if (errMap1) {
        this.activeKey = 'outboundOrderBatchItem'
        return
      }
      if (this.outboundOrderBatchItemTable.dataSource && this.outboundOrderBatchItemTable.dataSource.length > 0) {
        outboundRecordItem.push(...this.outboundOrderBatchItemTable.dataSource)
      }
      const formData = {
        ...this.model,
        outboundOrderId: this.model.id,
        id: null,
        createBy: null,
        createTime: null,
        outboundRecordItemList: outboundRecordItem.map(item => {
          return {
            ...item,
            id: null,
            createBy: null,
            createTime: null
          }
        })
      }
      this.request(formData)
    },
    request(formData) {
      this.confirmLoading = true
      postAction(this.url.add, formData)
        .then((res) => {
          if (res.success) {
            this.model.dataId = res.message
            this.applySubmit(this.model)
            this.$message.success('保存成功')
            this.$emit('ok')
            this.close()
          } else {
            this.$message.warning(res.message)
          }
        })
        .finally(() => {
          this.confirmLoading = false
        })
    },
    applySubmit(record) {
      if (record.dataId && record.dataId.length < 1) {
        this.$message.error('审批时必须传入参数dataId')
        return
      }
      //对于自定义业务，判断是否是驳回或退回的第一个发起人节点
      isFirstInitiator(record.dataId, record).then((res) => {
        if (res.success && res.result) {
          // 只有第一次能自动申请
        } else {
          const params = Object.assign({ dataId: record.dataId }, record)
          definitionStartByDataId(record.dataId, 'outboundRecordService', params)
            .then((res) => {
              if (res.success) {
                this.$message.success(res.message)
              } else {
                this.$message.error(res.message)
              }
              this.$emit('ok')
            })
        }
      })
    }
  }
}
</script>

<style scoped>
</style>